package org.semanticflash.rdf.values
{
	
	
	import com.adobe.net.URI;
	import com.adobe.utils.DateUtil;
	import com.bigflexlib.utils.Words;
	
	import org.semanticflash.rdf.triple.RDFTriple;
	import org.semanticflash.rdf.vocab.Vrdf;
	import org.semanticflash.rdf.vocab.Vxsd;
	
	
	
	
	/**
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */	
	public class RDFValueCodec
	{




		public static function fromAS3( value:* ):RDFValue
		{
			
			if ( value is RDFValue )
				return value;


			if ( value is RDFTriple )
				return ( value as RDFTriple ).s;
		
			
			if ( value is URI )
				return IRI.instance4( value as URI );
		
		
            if ( value is QName )
                return IRI.instance( ( value as QName ).uri );
			
		
			if ( value is Boolean )
				return RDFTypedLiteral.instance( value ? Words._true : Words._false, Vxsd._boolean );
			

			if ( value is String )
				return RDFTypedLiteral.instance( String( value ), Vxsd._string );
						

			if ( value is Date )
				return RDFTypedLiteral.instance( DateUtil.toW3CDTF( value as Date ) , Vxsd._dateTime );			


			if ( value is XML )
				return RDFTypedLiteral.instance( ( value as XML ).toString(), Vrdf._XMLLiteral );	
			

			if ( !isNaN( value ) ) // numeric
			{
				if ( value is int )
					return RDFTypedLiteral.instance( String( value ) , Vxsd._int );
			
				return RDFTypedLiteral.instance( String( value ), Vxsd._double );		// TODO: review this
			
			}

			
			return null;  // TODO

		}
		
		
		
		
		public static function toAS3( value:* ):*
		{
			
			if ( !(value is RDFValue) )
				return value;
			
			
			if ( value is IRI ) // TODO: review this ( use QName? how? )
				return value;
			
			
			if ( value is RDFLangLiteral ) // TODO: note that language is discarded
				return ( value as RDFLangLiteral ).lexicalValue;			


			if ( value is RDFPlainLiteral )
				return ( value as RDFPlainLiteral ).lexicalValue;			
			
			

			if ( value is RDFTypedLiteral )
			{
				var lexicalValue	:String 	= ( value as RDFTypedLiteral ).lexicalValue;
				var type			:IRI 		= ( value as RDFTypedLiteral ).datatype;		
				
				switch ( type.stringForm )
				{
					
					case Vxsd._boolean.stringForm :
					
						if ( lexicalValue == null )							return false;
						
						if ( lexicalValue.toLowerCase() == Words._true ) 	return true;
						if ( lexicalValue == "1" ) 							return true;
						if ( lexicalValue.toLowerCase() == Words._false ) 	return false;
						if ( lexicalValue == "0" ) 							return false;
						
						return undefined;
					
					break;
				
				
					case Vrdf._XMLLiteral :
					
						return new XML( lexicalValue ); // we don't keep an XML cache because instances could be modified
					
					break;
				
				
					
					case Vxsd._dateTime.stringForm:
					case Vxsd._date.stringForm:
						// virtuoso uses a space instead of a T (?)
						lexicalValue = lexicalValue.split(" ").join("T");
						var d:* = undefined;
						try { 
							d = DateUtil.parseW3CDTF( lexicalValue );
						} catch ( e:Error ){ }
						return d;
					break;
					
				
					case Vxsd._double.stringForm:
					case Vxsd._int.stringForm:
					case Vxsd._integer.stringForm:
					case Vxsd._float.stringForm:
						
						var num:Number = Number( lexicalValue );
						if ( isNaN( num ) ) 
							return undefined;
						return num;
				
					break;
					
					case Vxsd._string.stringForm:
						
						return lexicalValue;
					
					break;
				
				}
				
			
				
			
			}
			
			
			return undefined; // ????
		
		}





	}
	
}	